Skip to content

Lower gamma_correct so the LEDs dim below 28/255 - #20

Closed
bharvey88 wants to merge 2 commits into
betafrom
fix/led-low-brightness-gamma
Closed

Lower gamma_correct so the LEDs dim below 28/255#20
bharvey88 wants to merge 2 commits into
betafrom
fix/led-low-brightness-gamma

Conversation

@bharvey88

Copy link
Copy Markdown
Contributor

Version: 26.8.26.4

What does this implement/fix?

Setting a zone below 28/255 turned the LEDs off completely while the entity still reported on. This was not a dimming limit, it was quantization.

gamma_correct defaults to 2.8, and calculate_gamma_table() computes gamma_table_[i] = round((i/255)^gamma * 255). At that exponent every index from 0 to 27 rounds to 0, so any brightness under 28/255 was written as literal off.

Lowering it to 1.5 brings the first value that lights up down to 4/255 while keeping a perceptual curve rather than going fully linear:

gamma_correct First value that lights up
2.8 (default) 28 / 255
2.0 12 / 255
1.5 (this PR) 4 / 255
1.0 or 0 1 / 255

Set on the six partitions rather than on led_chain, because the partition's correction is the one that applies. light_partition.h get_view_internal() calls view.raw_set_color_correction(&this->correction_) for every pixel a partition writes, so a value on the parent chain would be inert.

Expected side effect, worth checking on hardware

Every fixed brightness in the config was tuned against the 2.8 curve, so they all render brighter now:

Where brightness: Was (2.8) Now (1.5)
play_song_* light shows 80% 53.5% 71.6%
statusCheck and testScript 40% 7.7% 25.3%

The status colors are the big move, from nearly invisible to clearly visible. That may be an improvement rather than a regression, but it is a visible change and it should be looked at. This PR deliberately changes only gamma_correct so the effect is unambiguous; retuning those fixed values to preserve the old appearance can be a follow-up if the new levels are too bright.

Types of changes

  • Bugfix (fixed change that fixes an issue)
  • New feature (thanks!)
  • Breaking change (repair/feature that breaks existing functionality)
  • Dependency Update - Does not publish
  • Other - Does not publish
  • Website of github readme file update - Does not publish
  • Github workflows - Does not publish

Checklist / Checklijst:

  • The code change has been tested and works locally
  • The code change has not yet been tested

If user-visible functionality or configuration variables are added/modified:

  • Added/updated documentation for the web page

esphome config passes on both H-3.yaml and H-3D.yaml, and all six partitions carry the value in the merged config. Not yet tested on hardware.

🤖 Generated with Claude Code

gamma_correct defaults to 2.8, and calculate_gamma_table() computes
round((i/255)^gamma * 255), so indices 0 through 27 all map to 0. Below
28/255 the LEDs were driven fully off rather than dim, while the entity
still reported on.

1.5 brings the first lit value down to 4/255 and keeps a perceptual
curve rather than going fully linear.

Set on the partitions because that is the correction that applies:
light_partition.h get_view_internal() calls raw_set_color_correction()
with the partition's own correction for every pixel it writes, so the
parent chain's value would be inert.

Version 26.8.26.4

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@bharvey88 bharvey88 added the bugfix Something isn't working label Aug 27, 2026
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ac4e8c34-6298-4be1-9175-fdbd30741e85


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…s-gamma

# Conflicts:
#	Integrations/ESPHome/Core.yaml
@bharvey88

Copy link
Copy Markdown
Contributor Author

Closing this. It treats a symptom, and the root cause is upstream.

The dead zone below 28/255 is not a dimming limit. Every gamma value bottoms out at the same place, output 1/255, which is the hardware floor for a WS2812:

gamma 2.8   slider  28 -> output 1
gamma 2.0   slider  12 -> output 1
gamma 1.5   slider   4 -> output 1
gamma 1.0   slider   1 -> output 1

So lowering gamma does not produce a dimmer ornament. It only changes which slider position reaches the floor that was already reachable. The ornament at 28/255 today is already as dim as the hardware goes.

What it does change is everything else. The 54 hard-coded brightness values in the config are slider-side numbers that pass through the same curve, so they all render brighter. statusCheck at brightness: 40% goes from 7.7% to 25.3%, and testScript at 30% goes from 3.4% to 16.4%. That is a large visual change to buy nothing at the low end.

The actual defect is in ESPHome. gamma_correct_ converts the 16-bit gamma table entry back to 8 bits with (value + 128) / 257, and (1 + 128) / 257 is 0, so small values are written to the strip as fully off while the light reports on. Filed upstream as esphome/esphome#18842.

Once that lands, the dead zone goes away with no change to this repo at all.

@bharvey88 bharvey88 closed this Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant